package arena.base;

import java.awt.Point;
import java.util.Vector;

import arena.entity.CheckPoint;
import arena.entity.RestorePoint;
import arena.entity.SwordItem;
import arena.entity.TeleportHole;
import arena.iterator.Iterator;
import arena.soldier.*;
import arena.weapon.SoldierWithSword;
import gameframework.base.ObservableValue;
import gameframework.game.GameEntity;
import gameframework.game.GameUniverse;
import gameframework.game.OverlapRulesApplierDefaultImpl;

public class ArenaOverlapRules extends OverlapRulesApplierDefaultImpl{
	protected GameUniverse universe;
	protected Point heroStartPos;
	protected Point monsterStartPos;
	private final ObservableValue<Integer> score;
	private final ObservableValue<Integer> life;
	private final ObservableValue<Boolean> endOfGame;
	static final int INVULNERABLE_DURATION = 20;
	protected int nbMonsterMax = 0;
	protected int nbMonster = 0;
	
	protected Vector<ArmedUnitSoldier> vMonster = new Vector<ArmedUnitSoldier>();
		
	public ArenaOverlapRules(Point heroPos, Point monsterPos,
			ObservableValue<Integer> life, ObservableValue<Integer> score,
			ObservableValue<Boolean> endOfGame, int nbMonster) {
		heroStartPos = (Point) heroPos.clone();
		monsterStartPos = (Point) monsterPos.clone();
		this.life = life;
		this.score = score;
		this.endOfGame = endOfGame;
		this.nbMonsterMax = nbMonster;
		this.nbMonster = nbMonster;
	}
	
	public void setUniverse(GameUniverse universe) {
		this.universe = universe;		
	}
	
	public void addMonster(ArmedUnitSoldier a) {
		vMonster.addElement(a);
	}
	
	public void overlapRule(SoldierWithSword hero, ArmedUnitSquad s) {		
		if(hero.isFighting()){
			Iterator iterateur = s.getIterator();
			
			//Elimination des entités on utilise l'iterateur
			while(iterateur.getNextElement()!=null){
				universe.removeGameEntity((GameEntity) iterateur.getCurrentElement());
				iterateur.getNextElement();
			}
			
			universe.removeGameEntity(s);
			
			hero.setInvulnerable(INVULNERABLE_DURATION);
		}
	}

	//Quand le hero n'a toujours pas d'arme
	public void overlapRule(HeroMan hero, SwordItem sw) {
		universe.removeGameEntity(sw);
		System.out.println(hero.getName() + " vient de prendre une épée !");
				
		//Decoration
		SoldierGame newHero = new SoldierWithSword(hero);
		
		//Dans la stratégie de mouvement, on met le nouvel hero.
		hero.getMoveStrategy().setHero(newHero);
				
		newHero.setPosition(hero.getPosition());
		newHero.setDriver(hero.getDriver());	
		
		//On supprime l'ancien hero et on met le nouveau, decoré.
		universe.removeGameEntity(hero);
		universe.addGameEntity(newHero);
	}
	
	//Sans arme le hero ne peut battre les monstres !
	public void overlapRule(HeroMan hero, GhostMonster im) {
		if(hero.isVulnerable()){
			System.out.println("Il ne faut pas s'approcher des monstres sans avoir d'arme !");
			hero.setPosition(heroStartPos);
		}
	}
	
	public void overlapRule(SoldierWithSword hero, GhostMonster im) {
		if(hero.isFighting()){
			universe.removeGameEntity(im);
			score.setValue(score.getValue() + 5);
			nbMonster--;
		}
		else{
			if(hero.isVulnerable()){
				float dammage = im.strike();
				if(life.getValue()>dammage){
				life.setValue(life.getValue() - (int)dammage);
				hero.setHealthPoint(hero.getHealthPoint() - dammage);				
				//On rend le hero invulnérable quelque secondes pour que sa vie ne descende pas complètement d'un coup !				
				hero.setInvulnerable(INVULNERABLE_DURATION);
				}
				else{
					if(hero.isSaveInMemento()){
						hero.restoreCheckPoint();
						life.setValue((int) hero.getHealthPoints());
						hero.setPosition(hero.getRegenerePoint());
					}
					else{
						life.setValue(0);
						hero.setHealthPoint(0);	
					}
				}
			}
		}
		
	}
	
	public void overlapRule(SoldierWithSword hero, TeleportHole th) {
		if(nbMonster==0){
			endOfGame.setValue(true);
		}
	}
	
	public void overlapRule(SoldierWithSword hero, CheckPoint c) {
		if(hero.isVulnerable()){
			Point save = (Point) c.getPosition().clone();
			save.x = save.x +c.getBoundingBox().width;
			hero.saveCheckPoint(save);
			hero.setInvulnerable(INVULNERABLE_DURATION);
		}
	}
	
	public void overlapRule(SoldierWithSword hero, RestorePoint c) {
		hero.restoreCheckPoint();
		life.setValue((int) hero.getHealthPoints());
	}
	
	public void overlapRule(Bullet bullet, ArmedUnitSoldier as) {
		if  (as.receiveAttack(bullet.getDamage())){
			universe.removeGameEntity(as);
			score.setValue(score.getValue() + 5);
			nbMonster--;
		}
	}
	
	public void overlapRule(SoldierWithSword hero, ArmedUnitSoldier as) {
		if(hero.isFighting()){
			float dammage = hero.strike();
			
			if (as.receiveAttack(dammage)){
				universe.removeGameEntity(as);
				score.setValue(score.getValue() + 5);
				nbMonster--;
			}
			
			if(nbMonster<nbMonsterMax){
				System.out.println("Un des leur est mort ! Les monstres s'enragent !!");
				for(ArmedUnitSoldier m : vMonster){
					m.notify(m);
				}
			}
		}		
		else{
			if(hero.isVulnerable()){
				float dammage = as.strike();
				hero.receiveAttack(dammage);
				hero.setInvulnerable(INVULNERABLE_DURATION);
				if(life.getValue()>dammage){
					life.setValue(life.getValue() - (int)dammage);
				}
				else{
					if(hero.isSaveInMemento()){
						hero.restoreCheckPoint();
						life.setValue((int) hero.getHealthPoints());
						hero.setPosition(hero.getRegenerePoint());
					}
					else{
						life.setValue(0);
					}
				}
			}
		}
	}
}
